package com.zrar.ak.gkpt.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zrar.ak.gkpt.model.vo.UserVO;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

/**
 * @ClassName: CommonTools
 * @Description: 通用工具类
 * @author: liyang
 * @date: 2020年2月25日
 */
public class CommonTools {

    private static ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 根据json字符串转换为对应的对象集合
     *
     * @param jsonData json字符串
     * @param T
     * @return
     * @throws IOException
     */
    public static List<?> jsonStrToList(String jsonData, Class<?> T) throws IOException {
        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, T);
        List<?> list = (List<?>) objectMapper.readValue(jsonData, javaType);
        return list;
    }


    /**
     * 根据json字符串转换为对应的对象
     *
     * @param jsonData json字符串
     * @param cls
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> T jsonStrToObject(String jsonData, Class<T> cls) throws IOException {
        return (T) objectMapper.readValue(jsonData, cls);
    }

    /**
     * 将对象转换成json字符串（不忽略对象里为null的字段）
     *
     * @param object
     * @return
     * @throws JsonProcessingException
     */
    public static String objectToJsonStr(Object object) {
        String jsonData = null;
        objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        try {
            jsonData = objectMapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonData;
    }

    /**
     * 将对象转换成json字符串（忽略过滤掉对象里为null的字段）
     *
     * @param object
     * @return
     * @throws JsonProcessingException
     */
    public static String objectToJsonStrIgnoreNull(Object object) {
        ObjectMapper objectMapperIgnoreNull = new ObjectMapper();
        String jsonData = null;
        objectMapperIgnoreNull.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        try {
            jsonData = objectMapperIgnoreNull.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return jsonData;
    }


    /**
     * 获取32位uuid
     *
     * @return
     */
    public static String getUUID() {
        return UUID.randomUUID().toString().replace("-", "");
    }


    /**
     * g根据传入的JsonResultEnum枚举给JsonResult对象赋值并返回
     * @param jsonResult
     * @param jsonResultEnum
     * @return
     */
    public static JsonResult jsonResultSetParameter(JsonResult jsonResult, JsonResultEnum jsonResultEnum){
        jsonResult.setCode(jsonResultEnum.getCode());
        jsonResult.setMsg(jsonResultEnum.getValue());
        return jsonResult;
    }



    /**
     * 将一个对象转换为另一个对象需要两个bean对象的变量相同
     *
     * @param <T1>      要转换的对象
     * @param <T2>      转换后的类
     * @param orimodel  要转换的对象
     * @param castClass 转换后的类
     * @return 转换后的对象
     */
    public static <T1, T2> T2 convertBean(T1 orimodel, Class<T2> castClass) {
        T2 returnModel;
        try {
            returnModel = castClass.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建" + castClass.getName() + "对象失败");
        }
        //要转换的字段集合
        List<Field> fieldlist = new ArrayList<Field>();
        final String objClass = "java.lang.object";
        //循环获取要转换的字段,包括父类的字段
        while (castClass != null && !objClass.equals(castClass.getName().toLowerCase())) {
            fieldlist.addAll(Arrays.asList(castClass.getDeclaredFields()));
            //得到父类,然后赋给自己
            castClass = (Class<T2>) castClass.getSuperclass();
        }
        for (Field field : fieldlist) {
            PropertyDescriptor getpd;
            PropertyDescriptor setpd;
            try {
                getpd = new PropertyDescriptor(field.getName(), orimodel.getClass());
                setpd = new PropertyDescriptor(field.getName(), returnModel.getClass());
            } catch (Exception e) {
                continue;
            }
            try {
                Method getMethod = getpd.getReadMethod();
                Object transValue = getMethod.invoke(orimodel);
                Method setMethod = setpd.getWriteMethod();
                setMethod.invoke(returnModel, transValue);
            } catch (Exception e) {
                throw new RuntimeException("cast " + orimodel.getClass().getName() + "to "
                        + castClass.getName() + " failed");
            }
        }
        return returnModel;
    }
}
